# -*- coding: utf-8 -*-
"""
ECharts 基础组件
"""
from PySide6.QtWebEngineWidgets import QWebEngineView
from PySide6.QtWidgets import QVBoxLayout
from pyecharts.charts.base import Base as EChartBase
from ..base import TgBaseWidget
import pandas as pd
import logging

logger = logging.getLogger(__name__)


class TgEchartsBase(TgBaseWidget):
    """ECharts 图表基础组件"""

    def __init__(self, parent=None):
        super().__init__(parent)
        self.chart = None
        self.webview = None
        self.df = None
        self.chart_title = ""
        self.setup_ui()

    def setup_ui(self):
        """初始化UI"""
        self.webview = QWebEngineView()
        # 当内容加载完成后，触发一次前端 resize，避免首次显示为空白
        try:
            self.webview.loadFinished.connect(self._on_load_finished)
        except Exception as e:
            # 理论上不会失败，但保持一致日志规则
            logger.exception(e)
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.addWidget(self.webview)

    def render_chart(self, chart: EChartBase):
        """渲染图表"""
        self.chart = chart
        
        # 直接渲染为HTML内容，不使用临时文件
        # 包裹一层基础模板，重置 body 默认边距并隐藏滚动条，避免出现垂直滚动条
        embedded = self.chart.render_embed()
        html_content = (
            "<html><head><meta charset='utf-8'>"
            "<style>html,body{margin:0;padding:0;overflow:hidden;background:transparent;}</style>"
            "</head><body>" + embedded + "</body></html>"
        )
        self.webview.setHtml(html_content)

    def _on_load_finished(self, ok: bool):
        """页面加载完成时触发前端 resize，确保首次渲染尺寸正确"""
        try:
            if not ok:
                # 页面加载失败一般不常见，这里仅记录
                logger.warning("ECharts page load failed in QWebEngineView")
                return
            self._trigger_resize_event()
        except Exception as e:
            logger.exception(e)

    def _trigger_resize_event(self):
        """在 Web 环境中派发一次 window.resize 事件，触发 ECharts 自适应"""
        try:
            page = getattr(self.webview, "page", None)
            page = page() if callable(page) else page
            if page is not None:
                # 使用 setTimeout 推迟到渲染循环后执行，确保 DOM/图表实例已创建
                page.runJavaScript(
                    'setTimeout(function(){window.dispatchEvent(new Event("resize"));}, 0);'
                )
        except Exception as e:
            logger.exception(e)

    def set_data(self, df: pd.DataFrame, **kwargs):
        """
        设置图表数据 (基类方法，子类需要重写)
        :param df: 数据DataFrame
        :param kwargs: 其他参数
        """
        raise NotImplementedError("子类必须实现 set_data 方法")

    def set_title(self, title: str):
        """设置图表标题"""
        self.chart_title = title
        return self

    def resizeEvent(self, event):
        """在窗口尺寸变化时，重新渲染以匹配容器大小"""
        super().resizeEvent(event)
        try:
            if hasattr(self, 'update_chart') and getattr(self, 'df', None) is not None:
                self.update_chart()
            # 同时派发一次前端 resize，尽量避免仅靠重渲染
            self._trigger_resize_event()
        except Exception as e:
            logger.exception(e)

    def showEvent(self, event):
        """组件显示时，触发一次前端 resize，避免首次显示空白需要点击"""
        try:
            super().showEvent(event)
            self._trigger_resize_event()
        except Exception as e:
            logger.exception(e)

